package folder.main.exp0.controllers.heuristic.delay;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import folder.main.exp0.controllers.heuristic.Heuristic;
import folder.model.network.Network;
import folder.model.node.Node;

public class SND_Hversion extends Heuristic
{
	public SND_Hversion( Network network, double[][] delays, int T )
	{
		super( network, delays, T );
		
		this.setMatches( this.minimizing( this.matching( this.arranging() ) ) );
	}
	
	protected List< Node > arranging()
	{
		double longestDelays[] = this.longestDelays();
	
		LinkedHashMap< Node, Double > pairs = new LinkedHashMap< Node, Double >();
		
		for( Node node: network.getNodes() )
			pairs.put( node, longestDelays[ node.getIdentifier() ] );
		
		LinkedHashMap< Node, Double > arrangedPairs = new LinkedHashMap< Node, Double >();
		
		while( !pairs.isEmpty() )
		{
			Iterator< Entry< Node, Double > > iterator = pairs.entrySet().iterator();
			double delay = Integer.MAX_VALUE;
			Node node = null;
									
			while( iterator.hasNext() )
			{
				Entry< Node, Double > entry = iterator.next();
				
				if( entry.getValue() < delay )
				{
					node = entry.getKey();
					delay = entry.getValue();
				}
			}
			
			arrangedPairs.put( node, delay );
			pairs.remove( node );
		}
		
		List< Node > arranging = new ArrayList< Node >();
		arranging.addAll( arrangedPairs.keySet() );
		
		return arranging;
	}
	private double[] longestDelays()
	{
		double longestDelays[] = new double[ network.getNumberNodes() ];
		
		for( Node nodeA: network.getNodes() )
		{
			double longestDelay = 0;
			
			for( Node nodeB: network.getNodes() )
			{
				double delay = delays[ nodeA.getIdentifier() ][ nodeB.getIdentifier() ];
				
				if( nodeA.getIdentifier() != nodeB.getIdentifier() && delay > longestDelay )
					longestDelay = delay;
			}
			
			longestDelays[ nodeA.getIdentifier() ] = longestDelay;
		}
		
		return longestDelays;
	}
	
    private class ThisComparator implements Comparator< Node >
    {
    	@Override
    	public int compare( Node nodeX, Node nodeY )
    	{    
    		Double tNodeX = nodeX.getDelayToNodeTargetMean();
    		Double tNodeY = nodeY.getDelayToNodeTargetMean();
    		
    		return tNodeX.compareTo( tNodeY );
    	}
    }
	
}
